<template>
  <div class="box">
    <div id="map">
      <el-button @click="changeVideo">视频投放</el-button>
      <div class="info" ref="info"></div>
    </div>
    <!-- <video
      controls
      autoplay
      autopictureinpicture
      ref="videos"
      muted
      @play="onPlay"
      @error="onError"
      style="display: none"
    >
      <source src="@/assets/1.mp4" type="video/mp4" />
      Your browser does not support the video tag.
    </video> -->

    <video
      id="trailer"
      autoplay
      loop
      crossorigin
      controls
      style="display: none"
      ref="videos"
    >
      <source src="@/assets/1.mp4" type="video/mp4" />
    </video>
  </div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, inject } from "vue";
import { useRoute, useRouter } from "vue-router";
import {
  viewerOptions,
  tokentoken,
  compassOptions,
} from "/public/config/cesiumConfig.js";

var viewer, addDataSource;
const info = ref(null);
const init = () => {
  Cesium.Ion.defaultAccessToken = tokentoken;
  viewer = new Cesium.Viewer("map", viewerOptions);
  viewer.clock.shouldAnimate = true;

  /**
   * // 加速——速度 * 2：
viewer.clockViewModel.multiplier *= 2;

// 减速——速度 / 2
viewer.clockViewModel.multiplier /= 2;

// 开始/暂停
viewer.clock.shouldAnimate = true/false;

// 重置
viewer.clock.currentTime = viewer.clock.startTime;

// 循环/不循环
// 时间轴执行完后停止（LOOP_STOP为循环，UNBOUNDED为继续读秒）
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;

   */
  viewer._cesiumWidget._creditContainer.style.display = "none"; //去掉logo
  // viewer.sceneMode = Cesium.SceneMode.SCENE2D;

  viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
    url: "http://localhost:666/map/dixing",
    // url: "http://localhost:666/map/dem-china",
    requestVertexNormals: true, // 请求法线信息，如果不需要可以不要这个选项
    requestWaterMask: true, //一个布尔类型，表示是否请求水面遮罩信息
    hasVertexNormals: true, //只读布尔值，表示该地形提供器是否包含顶点法线信息
    hasWaterMask: true, //只读布尔值，表示该地形提供器是否包含水面遮罩信息
    errorEvent: true, //Event类型，当地形数据请求错误时触发
    availability: true, //定义地形数据可用性的TimeIntervalCollection对象
  });

  addDataSource = new Cesium.CustomDataSource("addDataSource");
  viewer.dataSources.add(addDataSource);
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(116, 39, 500000),
    duration: 1,
  });

  viewer.debugShowFramesPerSecond = true; //显示当前的帧率信息，这样你就可以实时观察到地图的渲染性能
  viewer.scene.screenSpaceCameraController.minimumZoomDistance = 1; // 设置了摄像机的最小缩放距离
  viewer._cesiumWidget._creditContainer.style.display = "none"; //去掉logo
  viewer.scene.highDynamicRange = true;
  viewer.scene.screenSpaceCameraController.enableCollisionDetection = false;
  var scene = viewer.scene;
  // viewer.scene.logarithmicDepthBuffer = true
  // 获取具有自定义鼠标样式的元素
  var element = scene.canvas;
  // 添加自定义鼠标样式的类名
  //   element.classList.add("custom-cursor");
  Cesium.Math.setRandomNumberSeed(3);
  viewer.scene.fxaa = true;
  viewer.scene.postProcessStages.fxaa.enabled = true;
  if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
    var vtxf_dpr = devicePixelRatio;
    // 适度降低分辨率
    while (vtxf_dpr >= 2.0) {
      vtxf_dpr /= 2.0;
    }
    viewer.resolutionScale = vtxf_dpr;
  }
  viewer._container.style.cursor = "pointer";

  // 鼠标滑过

  var ellipsoid = scene.globe.ellipsoid;
  let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  handler.setInputAction((movement) => {
    // var cartesian = scene.camera.pickEllipsoid(movement.endPosition, Cesium.Ellipsoid.WGS84) //位置数据转换只地理数据类型
    var cartesian = scene.camera.pickEllipsoid(movement.endPosition, ellipsoid); //位置数据转换只地理数据类型

    if (cartesian) {
      // console.log(movement.endPosition);
      //能获取，显示坐标
      var cartographic = ellipsoid.cartesianToCartographic(cartesian); //cesium函数转换至地理数据类型的经纬度
      var ray = viewer.camera.getPickRay(movement.endPosition);
      // console.log(ray);
      if (ray) {
        var cartesian1 = viewer.scene.globe.pick(ray, viewer.scene);
        if (cartesian1) {
          var cartographic = Cesium.Cartographic.fromCartesian(cartesian1);
          var height = cartographic.height; // 的值为地形高度
        }
      }
      // console.log(height);

      var coords =
        "经度：" +
        Cesium.Math.toDegrees(cartographic.longitude).toFixed(4) +
        " " +
        "纬度：" +
        Cesium.Math.toDegrees(cartographic.latitude).toFixed(4) +
        " " +
        "相机高度：" +
        Math.ceil(viewer.camera.positionCartographic.height) +
        " " +
        " 高程：" +
        height +
        "米";

      info.value.innerHTML = coords;
      info.value.style.display = "block";
    } else {
      info.value.style.display = "none";
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
};
const videos = ref(null);
function addVideo() {
  let videoElement = videos.value;
  viewer.showRenderLoopErrors = false;
  viewer.shouldAnimate = true;
  viewer.entities.add({
    polygon: {
      hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights([
        113.2321, 23.1172, 5, 113.2315, 23.1172, 5, 113.2315, 23.1178, 5,
        113.2321, 23.1178, 5,
      ]),
      material: videoElement, // 将材质设置为video元素
      clampToGround: true,
    },
  });
  viewer.flyTo(viewer.entities);
}

// 视频投放
const videoFlag = ref(false);

var video;
var synchronizer;
var flag = ref(true);
const changeVideo = () => {
  if (flag.value) {
    // video = viewer.entities.add({
    //   polygon: {
    //     hierarchy: new Cesium.PolygonHierarchy(
    //       Cesium.Cartesian3.fromDegreesArray([
    //         114.25, 30.34, 114.3, 30.34, 114.3, 30.36, 114.25, 30.36,
    //       ])
    //     ),
    //     classificationType: Cesium.ClassificationType.BOTH,
    //     material: videos.value,
    //   },
    // });
    // synchronizer = new Cesium.VideoSynchronizer({
    //   clock: viewer.clock,
    //   element: videos.value,
    // });
    var position = Cesium.Cartesian3.fromDegrees(116, 39, 0);
    var heading = Cesium.Math.toRadians(180.0);
    var pitch = Cesium.Math.toRadians(0);
    var roll = Cesium.Math.toRadians(1.0);

    var orientation = Cesium.Transforms.headingPitchRollQuaternion(
      position,
      new Cesium.HeadingPitchRoll(heading, pitch, roll)
    );
    video = viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(116, 39, 0),
      orientation,
      plane: {
        plane: new Cesium.Plane(Cesium.Cartesian3.UNIT_Y, 0.0),
        dimensions: new Cesium.Cartesian2(600000.0, 200000.0),
        material: new Cesium.ImageMaterialProperty({
          image: videos.value,
        }),
      },
    });
    viewer.flyTo(video);
    synchronizer = new Cesium.VideoSynchronizer({
      // clock: viewer.clock,
      // element: videos.value,
    });
  } else {
    videos.value.pause();
    video.show = false;
    videos.value.style.display = "none";
    viewer.entities.removeAll();
    synchronizer = synchronizer.destroy();
    video.playbackRate = 1.0;
  }
  flag.value = !flag.value;
};

onMounted(() => {
  init();
  // addVideo();
  viewer.shouldAnimate = true;
  var position = Cesium.Cartesian3.fromDegrees(116, 39, 0);

  //添加爆炸模型
  addBomb(position);

  var planeModel = viewer.entities.add({
    // availability: new Cesium.TimeIntervalCollection([
    //   new Cesium.TimeInterval({
    //     start: djStartTime,
    //     stop: djEndTime
    //   })
    // ]),
    // position: property,
    position: position,
    // orientation: new Cesium.VelocityOrientationProperty(property),
    model: {
      uri: "http://localhost:666/map/models/huojian.glb",
      minimumPixelSize: 128,
      runAnimations: true, //是否显示动画
      clampAnimations: true, //是否保持最后一针的动画
      // maximumScale: 12000 //最大的模型像素
      clampToGround: true,
      // heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
    },
    path: {
      resolution: 1,
      material: new Cesium.PolylineGlowMaterialProperty({
        glowPower: 0.1,
        color: Cesium.Color.AQUA,
      }),
      width: 5,
    },
  });

  weatherFn(arr);
});
function addBomb(position) {
  console.log("爆炸");
  // 爆炸模型位置
  var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position);
  var offset = Cesium.Cartesian3.add(
    new Cesium.Cartesian3(0.0, 0.0, 0.0),
    Cesium.Cartesian3.ZERO,
    new Cesium.Cartesian3()
  );
  var emitterModelMatrix = Cesium.Matrix4.fromTranslation(
    offset,
    new Cesium.Matrix4()
  );
  viewer.scene.primitives.add(
    new Cesium.ParticleSystem({
      image: "/fire.png",
      imageSize: new Cesium.Cartesian2(20, 20),
      startScale: 1.0,
      endScale: 4.0,
      // Particle behavior
      particleLife: 1.0,
      speed: 5.0,
      loop: false,
      // Emitter parameters
      emitter: new Cesium.CircleEmitter(0.5),
      emissionRate: 2.0,
      modelMatrix: modelMatrix,
      emitterModelMatrix: emitterModelMatrix,
      lifetime: 2.0,
    })
  );
}

var arr = [
  {
    center: { lon: 116, lat: 39 },
    radius: 15000,
    temperature: 25,
    pressure: 2.5,
    humidity: 15,
    precipitation: 100,
    snowfall: 0,
    cloud: 20,
    visibility: 200,
  },
  {
    center: { lon: 116, lat: 41 },
    radius: 15000,
    temperature: 25,
    pressure: 2.5,
    humidity: 15,
    precipitation: 0,
    snowfall: 100,
    cloud: 20,
    visibility: 200,
  },
];

// 雨雪
function weatherFn(data) {
  data.forEach((v) => {
    if (v.precipitation != 0) {
      let rainPosition = Cesium.Cartesian3.fromDegrees(
        v.center.lon,
        v.center.lat
      );
      var scene = viewer.scene;
      // snow
      var snowParticleSize = scene.drawingBufferWidth / 100.0; //例子系统大小
      var snowRadius = v.radius; //雪的半径
      var minimumSnowImageSize = new Cesium.Cartesian2(
        snowParticleSize,
        snowParticleSize
      ); //最小 雪大小
      var maximumSnowImageSize = new Cesium.Cartesian2(
        snowParticleSize * 2.0,
        snowParticleSize * 2.0
      ); //最大 雪大小
      var snowSystem;

      var snowGravityScratch = new Cesium.Cartesian3(); //竖直位置--名词存疑-实际上是一个坐标
      //每个粒子系统在仿真过程种，都会调用更新回调函数来修改粒子的属性。
      // 回调函数传过两个参数，一个是粒子本身，另一个是仿真时间步长
      var snowUpdate = function (particle, dt) {
        //计算提供的笛卡尔坐标的标准化形式
        snowGravityScratch = Cesium.Cartesian3.normalize(
          particle.position,
          snowGravityScratch
        );
        //所提供的标量对所提供的笛卡尔分量进行多重变换。最后写入到snowGravityScratch中，随机下落的距离
        Cesium.Cartesian3.multiplyByScalar(
          snowGravityScratch,
          -1050.0,
          snowGravityScratch
        );
        particle.position = Cesium.Cartesian3.add(
          particle.position,
          snowGravityScratch,
          particle.position
        );
        //粒子速度，两个笛卡尔坐标相加--赋值到第三个分量中，等价于速度自增velocity+=velocity
        // particle.velocity = Cesium.Cartesian3.add(particle.velocity, snowGravityScratch, particle.velocity)
        //判断相机位置距离，
        var distance = Cesium.Cartesian3.distance(
          scene.camera.position,
          particle.position
        );
        //如果距离大于雪的半径，则透明度为0，否则逐渐增加
        particle.endColor.alpha =
          snowSystem.endColor.alpha / (distance / snowRadius + 0.1);
        if (distance > snowRadius) {
          particle.endColor.alpha = 0.0;
        } else {
          particle.endColor.alpha =
            snowSystem.endColor.alpha / (distance / snowRadius + 0.1);
        }
      };
      const rainParticleSize = 15.0;
      const rainImageSize = new Cesium.Cartesian2(
        rainParticleSize,
        rainParticleSize * 2.0
      );
      snowSystem = new Cesium.ParticleSystem({
        modelMatrix: new Cesium.Matrix4.fromTranslation(rainPosition), //粒子系统发射器的位置
        speed: -1.0,

        minimumSpeed: -1.0, //最小速度
        maximumSpeed: 0.0, //最大速度
        lifetime: 15.0, //例子生命周期长度
        emitter: new Cesium.SphereEmitter(snowRadius), //例子系统发射器，包裹圆形，椭圆，盒子，cone形状的发射器
        startScale: 1, //起始比例
        endScale: 0, //终止比例

        image: "/circular_particle.png",
        emissionRate: 9000.0, //每秒发射的粒子数量
        startColor: Cesium.Color.WHITE.withAlpha(0.0), //起始颜色
        endColor: Cesium.Color.WHITE.withAlpha(1.0), //终止颜色
        // startColor: new Cesium.Color(0.27, 0.5, 0.7, 0.0),
        // endColor: new Cesium.Color(0.27, 0.5, 0.7, 0.98),
        // minimumImageSize: minimumSnowImageSize, //最小大小
        // maximumImageSize: maximumSnowImageSize, //最大大小
        updateCallback: snowUpdate,
        imageSize: rainImageSize,
      });

      scene.primitives.add(snowSystem);
    } else if (v.snowfall != 0) {
      let rainPosition = Cesium.Cartesian3.fromDegrees(
        v.center.lon,
        v.center.lat
      );
      var scene = viewer.scene;
      // snow
      var snowParticleSize = scene.drawingBufferWidth / 100.0; //例子系统大小
      var snowRadius = v.radius; //雪的半径
      var minimumSnowImageSize = new Cesium.Cartesian2(
        snowParticleSize,
        snowParticleSize
      ); //最小 雪大小
      var maximumSnowImageSize = new Cesium.Cartesian2(
        snowParticleSize * 2.0,
        snowParticleSize * 2.0
      ); //最大 雪大小
      var snowSystem;

      var snowGravityScratch = new Cesium.Cartesian3(); //竖直位置--名词存疑-实际上是一个坐标
      //每个粒子系统在仿真过程种，都会调用更新回调函数来修改粒子的属性。
      // 回调函数传过两个参数，一个是粒子本身，另一个是仿真时间步长
      var snowUpdate = function (particle, dt) {
        //计算提供的笛卡尔坐标的标准化形式
        snowGravityScratch = Cesium.Cartesian3.normalize(
          particle.position,
          snowGravityScratch
        );
        //所提供的标量对所提供的笛卡尔分量进行多重变换。最后写入到snowGravityScratch中，随机下落的距离
        Cesium.Cartesian3.multiplyByScalar(
          snowGravityScratch,
          Cesium.Math.randomBetween(-30.0, -300.0),
          snowGravityScratch
        );
        //粒子速度，两个笛卡尔坐标相加--赋值到第三个分量中，等价于速度自增velocity+=velocity
        particle.velocity = Cesium.Cartesian3.add(
          particle.velocity,
          snowGravityScratch,
          particle.velocity
        );
        //判断相机位置距离，
        var distance = Cesium.Cartesian3.distance(
          scene.camera.position,
          particle.position
        );
        //如果距离大于雪的半径，则透明度为0，否则逐渐增加
        particle.endColor.alpha =
          snowSystem.endColor.alpha / (distance / snowRadius + 0.1);
        if (distance > snowRadius) {
            particle.endColor.alpha = 0.0;
        } else {
            particle.endColor.alpha = snowSystem.endColor.alpha / (distance / snowRadius + 0.1);
        }
      };

      snowSystem = new Cesium.ParticleSystem({
        modelMatrix: new Cesium.Matrix4.fromTranslation(rainPosition), //粒子系统发射器的位置
        minimumSpeed: -1.0, //最小速度
        maximumSpeed: 0.0, //最大速度
        lifetime: 15.0, //例子生命周期长度
        emitter: new Cesium.SphereEmitter(snowRadius), //例子系统发射器，包裹圆形，椭圆，盒子，cone形状的发射器
        startScale: 0.5, //起始比例
        endScale: 1.0, //终止比例
        image: "/snowflake_particle.png",
        // image: '/d3kit/rain.png',
        emissionRate: 7000.0, //每秒发射的粒子数量
        startColor: Cesium.Color.WHITE.withAlpha(0.0), //起始颜色
        endColor: Cesium.Color.WHITE.withAlpha(1.0), //终止颜色
        minimumImageSize: minimumSnowImageSize, //最小大小
        maximumImageSize: maximumSnowImageSize, //最大大小
        updateCallback: snowUpdate,
      });

      scene.primitives.add(snowSystem);
    }
  });
}
</script>
<style scoped lang="scss">
.box {
  width: 100%;

  height: 100%;
}
#map {
  width: 100%;

  height: 100%;
  border: 1px solid red;
  position: relative;
  .info {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
  }
  .el-button {
    position: absolute;
    top: 100px;
    left: 0;
    z-index: 2;
  }
}
</style>
